
/******************************************************************************
 *
 * jattbak - TODO
 *
 * Author:        Dennis Krzyzaniak
 * E-mail:        ebrosius@netgarage.org
 * Copyright (C): 2011 by Dennis Krzyzaniak
 *
 * This file is part of jattbak.
 *
 * jattbak is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * jattbak is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with jattbak.  If not, see <http://www.gnu.org/licenses/>.
 *
 *****************************************************************************/

/* =========== INCLUDES ==================================================== */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "base_dlist_test.h"

#include <stdlib.h>

#include "base_test.h"
#include "base_dlist.h"

/* =========== MODULE CONFIGURATION ======================================== */

/* =========== DEFINES ===================================================== */

/* =========== DATA TYPES ================================================== */

typedef struct {
   baseDlistNode_t baseNode;
   int one;
   int two;
} testNode_t;

/* =========== GLOBALS ===================================================== */

/* =========== PRIVATE PROTOTYPES ========================================== */

/* =========== PUBLIC FUNCTIONS ============================================ */

/*---------------------------------------------------------------------------*/
int
testBaseDlistAddRm(
      void
      )
{
   int testsFailed = 0;
   baseDlist_t list;
   int itemCnt = 0;
   int i;

   baseDlistInit(&list);

   /* add head */
   for (i=0; i<3; i++) {
      testNode_t* node = malloc(sizeof(*node));
      baseTest(node != NULL, &testsFailed);
      if (node != NULL) {
         node->one = 3 - i;
         node->two = 3 - i;
         baseDlistAddHead(&list, &node->baseNode);
      }
      itemCnt = baseDlistGetItemCount(&list);
      baseTest(itemCnt == i + 1, &testsFailed);
   }

   /* add tail */
   for (i=0; i<3; i++) {
      testNode_t* node = malloc(sizeof(*node));
      baseTest(node != NULL, &testsFailed);
      if (node != NULL) {
         node->one = i + 4;
         node->two = i + 4;
         baseDlistAddTail(&list, &node->baseNode);
      }
      itemCnt = baseDlistGetItemCount(&list);
      baseTest(itemCnt == i + 4, &testsFailed);
   }

   /* check content and free memory */
   itemCnt = baseDlistGetItemCount(&list);
   baseTest(itemCnt == 6, &testsFailed);
   for (i=0; i<itemCnt; i++) {
      baseDlistNode_t* baseNode = baseDlistRemoveHead(&list);
      testNode_t* node = (testNode_t*)baseNode;
      baseTest(node != NULL, &testsFailed);
      baseTest(node->one == i + 1, &testsFailed);
      baseTest(node->two == i + 1, &testsFailed);
      free(node);
   }

   itemCnt = baseDlistGetItemCount(&list);
   baseTest(itemCnt == 0, &testsFailed);

   return testsFailed;
}
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
int
testBaseDlistItemAccess(
      void
      )
{
   int testsFailed = 0;
   baseDlist_t list;
   testNode_t* node = NULL;
   baseDlistNode_t* baseNode = NULL;
   int itemCnt = 0;
   int i;

   baseDlistInit(&list);

   for (i=0; i<3; i++) {
      testNode_t* node = malloc(sizeof(*node));
      baseTest(node != NULL, &testsFailed);
      if (node != NULL) {
         node->one = 3 - i;
         node->two = 3 - i;
         baseDlistAddHead(&list, &node->baseNode);
      }
      itemCnt = baseDlistGetItemCount(&list);
      baseTest(itemCnt == i + 1, &testsFailed);
   }

   /* get head */
   baseNode = baseDlistGetHead(&list);
   baseTest(baseNode != NULL, &testsFailed);
   node = (testNode_t*)baseNode;
   baseTest(node->one == 1, &testsFailed);
   baseTest(node->two == 1, &testsFailed);

   /* get successor */
   baseNode = baseDlistGetSuccessor(baseNode);
   baseTest(baseNode != NULL, &testsFailed);
   node = (testNode_t*)baseNode;
   baseTest(node->one == 2, &testsFailed);
   baseTest(node->two == 2, &testsFailed);

   baseNode = baseDlistGetSuccessor(baseNode);
   baseTest(baseNode != NULL, &testsFailed);
   node = (testNode_t*)baseNode;
   baseTest(node->one == 3, &testsFailed);
   baseTest(node->two == 3, &testsFailed);

   /* get tail */
   baseNode = baseDlistGetTail(&list);
   baseTest(baseNode != NULL, &testsFailed);
   node = (testNode_t*)baseNode;
   baseTest(node->one == 3, &testsFailed);
   baseTest(node->two == 3, &testsFailed);

   /* get ancestor */
   baseNode = baseDlistGetAncestor(baseNode);
   baseTest(baseNode != NULL, &testsFailed);
   node = (testNode_t*)baseNode;
   baseTest(node->one == 2, &testsFailed);
   baseTest(node->two == 2, &testsFailed);

   baseNode = baseDlistGetAncestor(baseNode);
   baseTest(baseNode != NULL, &testsFailed);
   node = (testNode_t*)baseNode;
   baseTest(node->one == 1, &testsFailed);
   baseTest(node->two == 1, &testsFailed);

   /* free memory */
   for (i=0; i<3; i++) {
      baseNode = baseDlistRemoveHead(&list);
      node = (testNode_t*)baseNode;
      baseTest(node != NULL, &testsFailed);
      free(node);
   }

   itemCnt = baseDlistGetItemCount(&list);
   baseTest(itemCnt == 0, &testsFailed);

   return testsFailed;
}
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
int
testBaseDlistInsertRm(
      void
      )
{
   int testsFailed = 0;
   baseDlist_t list;
   testNode_t* node = NULL;
   baseDlistNode_t* baseNode = NULL;
   int itemCnt = 0;
   int i;

   baseDlistInit(&list);

   for (i=0; i<2; i++) {
      testNode_t* node = malloc(sizeof(*node));
      baseTest(node != NULL, &testsFailed);
      if (node != NULL) {
         node->one = 4 - 2 * i;
         node->two = 4 - 2 * i;
         baseDlistAddHead(&list, &node->baseNode);
      }
      itemCnt = baseDlistGetItemCount(&list);
      baseTest(itemCnt == i + 1, &testsFailed);
   }

   /* kind of add head */
   {
      node = malloc(sizeof(*node));
      baseTest(node != NULL, &testsFailed);
      if (node != NULL) {
         node->one = 1;
         node->two = 1;
         baseDlistInsertAfter(&list, NULL, &node->baseNode);
      }
      itemCnt = baseDlistGetItemCount(&list);
      baseTest(itemCnt == 3, &testsFailed);
   }

   /* insert in the middle */
   {
      node = malloc(sizeof(*node));
      baseTest(node != NULL, &testsFailed);
      if (node != NULL) {
         node->one = 3;
         node->two = 3;
         baseNode = baseDlistGetHead(&list);
         baseTest(baseNode != NULL, &testsFailed);
         baseNode = baseDlistGetSuccessor(baseNode);
         baseTest(baseNode != NULL, &testsFailed);
         baseDlistInsertAfter(&list, baseNode, &node->baseNode);
      }
      itemCnt = baseDlistGetItemCount(&list);
      baseTest(itemCnt == 4, &testsFailed);
   }

   /* insert add the end */
   {
      node = malloc(sizeof(*node));
      baseTest(node != NULL, &testsFailed);
      if (node != NULL) {
         node->one = 5;
         node->two = 5;
         baseNode = baseDlistGetTail(&list);
         baseTest(baseNode != NULL, &testsFailed);
         baseDlistInsertAfter(&list, baseNode, &node->baseNode);
      }
      itemCnt = baseDlistGetItemCount(&list);
      baseTest(itemCnt == 5, &testsFailed);
   }

   for (i=0; i<5; i++) {
      baseDlistNode_t* baseNode = baseDlistRemoveHead(&list);
      testNode_t* node = (testNode_t*)baseNode;
      baseTest(node != NULL, &testsFailed);
      baseTest(node->one == i + 1, &testsFailed);
      baseTest(node->two == i + 1, &testsFailed);
      free(node);
   }

   itemCnt = baseDlistGetItemCount(&list);
   baseTest(itemCnt == 0, &testsFailed);

   return testsFailed;
}
/*---------------------------------------------------------------------------*/

/* =========== PRIVATE FUNCTIONS =========================================== */

/* ========================== END OF FILE ================================== */

/*
 * vim settings, please do not remove!
 * vim:autoindent:
 * vim:ts=3:sw=3:sts=3:expandtab:cindent:tw=75:formatoptions=croql:
 * vim600:foldmethod=syntax:
 */
